<?php
namespace app\attachment\controller;

use think\Controller;
use Qiniu\Auth;
use Qiniu\Config;
use Qiniu\Storage\UploadManager;
use Qiniu\Storage\BucketManager;
use Qiniu\base64_urlSafeEncode;
use Qiniu\Processing\PersistentFop;


class Qiniu extends Controller
{
    public $bucket_url;
    protected $config;
    protected $client;
    protected $error;

    protected function initialize()
    {
        $this->config = config('zzcms.qiniu_info');
        $this->client = new Auth($this->config['access_key'], $this->config['secret_key']);
        $this->bucket_url = $this->config['url'];
    }


    /**
     * 图片裁剪
     * @param $url  图片地址
     * @param $filename  保存文件名
     * @param array $param 参数  宽，高，偏移量
     * @return bool|string
     */
    public function cropsize($url, $filename, $param = [])
    {
        //裁剪宽度
        $width = isset($param['width']) ? intval($param['width']) : 100;
        //裁剪高度
        $height = isset($param['height']) ? intval($param['height']) : 100;
        //X偏移量
        $offsetx = isset($param['offsetx']) ? intval($param['offsetx']) : 0;
        //Y偏移量
        $offsety = isset($param['offsety']) ? intval($param['offsety']) : 0;
        $result = $this->downloadUrl($filename, $url);
        if (!$result) {
            $this->error = '图片远程下载错误';
            return false;
        }
        return $this->saveas($filename, ['width' => $width, 'param' => "imageMogr2/auto-orient/crop/!{$width}x{$height}a{$offsetx}a{$offsety}/quality/85|imageslim"]);
    }


    /**
     * amr音频转mp3
     * @param $content
     * @param $filename
     * @return string
     */
    public function amr2mp3($content, $filename, $is_createfile = true)
    {
        if ($this->fileExist($filename)) {
            $signed_url = $this->client->privateDownloadUrl($this->bucket_url . $filename);
            return file_get_contents($signed_url);
        }
        $amr = str_replace('.mp3', '.amr', $filename);
        if (!$this->putFile($amr, $content)) {
            $this->error = '文件上传错误';
            return false;
        }
        $pfop = new PersistentFop($this->client, null);
        $fops = "avthumb/mp3/ab/320k/ar/44100/acodec/libmp3lame";
        //队列名字
        $pipeline = 'zzcmspipeline';
        $policy = [
            'persistentOps' => $fops,
            'persistentPipeline' => $pipeline
        ];
        $savekey = base64_urlSafeEncode($this->config['bucket'] . ':' . $filename);
        $fops = $fops . '|saveas/' . $savekey;
        $res = $pfop->execute($this->config['bucket'], $amr, $fops, $policy);
        if ($is_createfile) {
            if (is_null($res[1])) {
                if ($this->fileExist($filename)) {
                    $signed_url = $this->client->privateDownloadUrl($this->bucket_url . $filename);
                    return file_get_contents($signed_url);
                } else {
                    $this->error = '文件正在转换中';
                    return false;
                }
            }
            $this->error = '文件转换格式错误';
            return false;
        } else {
            return true;
        }
    }

    /**
     * 站内保存
     * @param $filename
     * @param int $width
     * @return string
     */
    public function saveas($filename, $param = [])
    {
        $width = isset($param['width']) ? intval($param['width']) : 1000;
        $image_param = isset($param['param']) ? $param['param'] : "imageView2/2/w/{$width}";
        //生成EncodedEntryURI的值
        $new_filename = str_replace('.', "_w{$width}.", $filename);
        //<Key>为生成缩略图的文件名
        $entry = $this->config['bucket'] . ':' . $new_filename;
        //Base64编码
        $encoded_entry_url = base64_urlSafeEncode($entry);
        //除去http
        $url_array = explode('://', $this->bucket_url);
        $domain = end($url_array);
        //使用SecretKey对新的下载URL进行HMAC1-SHA1签名
        $newurl = "{$domain}{$filename}?{$image_param}|saveas/" . $encoded_entry_url;
        $sign = hash_hmac("sha1", $newurl, $this->config['secret_key'], true);
        //对签名进行URL安全的Base64编码
        $encodedSign = base64_urlSafeEncode($sign);
        //最终得到的完整下载URL
        $image_url = "http://" . $newurl . "/sign/" . $this->config['access_key'] . ":" . $encodedSign;
        //访问页面
        /**
         * 访问页面得到结果
         * 正确：{"key":"66655566thumb.gif","hash":"FhE3gwCRBv6MK4Y0hNDctUGW1iTy"}
         */
        try {
            $result = file_get_contents($image_url);
            $array = json2array($result);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            return false;
        }
        return $this->bucket_url . $array['key'];
    }

    /**
     * 下载 文件
     * @param $object  文件名
     * @param $file   文件
     * @param string $param 图片处理规则
     * @return bool
     */
    public function downloadFile($object, $file, $param = '')
    {
        if (empty($param)) {
            $wh_array = getImageInfo($this->bucket_url . $object);
            if (empty($wh_array)) {
                $this->error = '图片无尺寸值';
                return false;
            }
            $width = $wh_array['width'] > 1000 ? 1000 : $wh_array['width'];
            $param = 'imageMogr2/auto-orient/thumbnail/' . $width . 'x/blur/1x0/quality/85|imageslim';
        }
        //设置文件夹的权限
        $this->ckeckDir($file);
        $url = $this->bucket_url . $object . '?' . $param;
        return downloadImage($url, $file);
    }

    /**
     * 抓取网络资源到空间
     * @param $object
     * @param $file
     * @param string $param
     * @return bool
     */
    public function downloadUrl($object, $url)
    {
        if (empty($url)) {
            return false;
        }
        $bucketManager = new BucketManager($this->client);
        list($ret, $err) = $bucketManager->fetch($url, $this->config['bucket'], $object);
        return $err !== null ? false : true;
    }


    /**
     * 生成URL
     * @param $object
     * @param string $param
     * @return mixed
     */
    public function createUrl($object, $param = '')
    {
        if (empty($param)) {
            $param = 'imageMogr2/auto-orient/thumbnail/1000x/blur/1x0/quality/75|imageslim';
        }
        $url = $this->bucket_url . $object . '?' . $param;
        $private_url = $this->client->privateDownloadUrl($url);
        return $private_url;
    }

    /**
     * 获取文件信息
     * @param $file
     * @return bool
     */
    public function getFileMeta($file)
    {
        $config = new Config();
        $bucketManager = new BucketManager($this->client, $config);
        list($fileInfo, $err) = $bucketManager->stat($this->config['bucket'], $file);
        if ($err) {
            $this->error = '七牛上传失败';
            return false;
        } else {
            return $fileInfo;
        }
    }


    /**
     * 上传字符串
     * @param $filename
     * @param $content
     * @return bool
     */
    public function putFile($filename, $content)
    {
        $token = $this->client->uploadToken($this->config['bucket']);
        $uploadMgr = new UploadManager();
//        preg_match('/^(data:\s*image\/(\w+);base64,)/', $content, $res);
//        $content = str_replace($res[1], '', $content);
        list($result, $error) = $uploadMgr->put($token, $filename, $content);
        if ($error === null) {
            return true;
        } else {
            $this->error = '七牛上传失败';
            return false;
        }
    }


    /**
     * 上传文件
     * 说明  当cateid=1时，表示七牛图片类型
     * @param $filename   上传到七牛的名字，包含路径，最好跟本地目录结构一样
     * @param $file_path  本地文件所在地址
     * @param int $userid
     * @param int $other
     * @return bool
     */
    public function upload($filename, $file_path)
    {
        $token = $this->client->uploadToken($this->config['bucket'], $filename);
        $uploadMgr = new UploadManager();
        list($result, $error) = $uploadMgr->putFile($token, $filename, $file_path);
        if ($error === null) {
            return true;
        } else {
            $this->error = '七牛上传失败';
            return false;
        }
    }


    /**
     * 抓取网络资源到空间
     * @param $url   图片地址
     * @param $filename  保存的文件名
     * @return bool
     */
    public function fetchImage($url, $filename)
    {
        $bucketManager = new BucketManager($this->client);
        list($ret, $err) = $bucketManager->fetch($url, $this->config['bucket'], $filename);
        return $err !== null ? false : true;
    }

    /**
     * 判断object是否存在
     * @param $object  文件名（含路径）
     * @return bool
     */
    public function fileExist($object)
    {
        $config = new Config();
        $bucketManager = new BucketManager($this->client, $config);
        list($fileInfo, $err) = $bucketManager->stat($this->config['bucket'], $object);
        if ($err) {
            $this->error = '七牛上传失败';
            return false;
        } else {
            return $fileInfo;
        }
    }

    /**
     * 删除object
     * @param $object
     *          单个文件或者文件数组
     *          $objects = array();
     *          $objects[] = "oss-php-sdk-test/upload-test-object-name.txt";
     *          $objects[] = "oss-php-sdk-test/upload-test-object-name.txt.copy";
     * @return bool
     */
    public function deleteFile($object)
    {
        $config = new Config();
        $bucketManager = new BucketManager($this->client, $config);
        if (is_array($object)) {
            //每次最多不能超过1000个
            $ops = $bucketManager->buildBatchDelete($this->config['bucket'], $object);
            list($ret, $err) = $bucketManager->batch($ops);
        } else {
            $err = $bucketManager->delete($this->config['bucket'], $object);
        }
        if ($err) {
            $this->error = '批量删除错误';
            return false;
        } else {
            return true;
        }

    }

    /**
     * 获取bucker
     * @return mixed
     */
    public function getBucker()
    {
        return $this->config['bucket'];
    }


    /**
     * 设置OSS的bucket
     * @param $bucket
     * @return mixed
     */
    public function setBucker($bucket)
    {
        return $this->config['bucket'] = $bucket;
    }

    /**
     * 返回错误信息
     * @return mixed
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     * 检测用户文件目录权限
     * @param $file
     */
    private function ckeckDir($file)
    {
        $dir_array = explode('/', $file);
        $dir = str_replace(end($dir_array), '', $file);
        if (!is_dir($dir)) {
            @mkdir($dir, 0777, true);
        }
    }


}
